package sk.tuke.constraintbuilder.views;
import java.util.ArrayList;
import java.util.StringTokenizer;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.core.IClassFile;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.core.JarPackageFragmentRoot;
import org.eclipse.jdt.internal.core.PackageFragment;
import org.eclipse.jdt.ui.wizards.BuildPathDialogAccess;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.ui.dialogs.ListSelectionDialog;
import org.eclipse.ui.forms.widgets.Form;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Hyperlink;
import org.eclipse.ui.forms.widgets.ImageHyperlink;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.model.BaseWorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.eclipse.wb.swt.SWTResourceManager;

import sk.tuke.constraintbuilder.editor.ConstraintEditorController;
import sk.tuke.constraintbuilder.editor.EditorInput;
import sk.tuke.constraintbuilder.handler.CallEditor;
import sk.tuke.constraintbuilder.model.Constraint;
import sk.tuke.constraintbuilder.model.Context;
import sk.tuke.constraintbuilder.model.RuleElement;
import sk.tuke.constraintbuilder.model.Model;
import sk.tuke.constraintbuilder.model.Severity;
import sk.tuke.constraintbuilder.model.SimpleRuleElement;
import sk.tuke.constraintbuilder.model.StructuredRuleElement;
import sk.tuke.constraintbuilder.model.Template;
import sk.tuke.constraintbuilder.utils.MyImages;
import sk.tuke.constraintbuilder.views.components.AnnotationChooserPanel;
import sk.tuke.constraintbuilder.views.components.ConstraintEditorDropAdapter;
import sk.tuke.constraintbuilder.views.components.IRulePanel;
import sk.tuke.constraintbuilder.views.components.RuleChooserPanel;
import sk.tuke.constraintbuilder.views.components.SimpleElementRulePanel;
import sk.tuke.constraintbuilder.views.components.StructuredElementRulePanel;
import sk.tuke.constraintbuilder.views.components.TypeChooserPanel;


public class ConstraintEditorView extends Composite {

	private final FormToolkit toolkit = new FormToolkit(Display.getCurrent());
	
	//Controller
	private ConstraintEditorController controller;
	
	//Gui Components
	private java.util.List<IRulePanel> rulePanels = new ArrayList<>();
	private Form editorForm;
	private Section templateSection;
	private Section rulesSection;
	private Section conditionSection;
	private Section annotationsListSection;
	private Section ruleChooserSection;
	private Section typeChooserSection;
	private Composite rulesSectionPanel;
	private Composite conditionSectionPanel;
	private Text annotationTextfield;
	private Text nameTextfield;
	private Text descriptionText;
	private ComboViewer comboViewer;
	private Combo contextCombo;
	private Combo severityCombo;
	private Label emptyRulePanelLabel;
	private Label emptyCondPanelLabel;

	

	/**
	 * Create GUI for constraint editor
	 * @param parent a widget which will be the parent of the new instance
	 * @param CEController a controller which control communication between model (constraint) and view (editor gui)
	 */
	public ConstraintEditorView(Composite parent, ConstraintEditorController CEController) {
		super(parent, SWT.NONE);
		this.controller=CEController;
		setBackground(SWTResourceManager.getColor(SWT.COLOR_WIDGET_BACKGROUND));
		addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent e) {
				toolkit.dispose();
			}
		});
		toolkit.adapt(this);
		toolkit.paintBordersFor(this);
		setLayout(new FillLayout(SWT.HORIZONTAL));
		
		editorForm = toolkit.createForm(this);
		toolkit.paintBordersFor(editorForm);
		editorForm.setText("Constraint Editor");
		editorForm.getBody().setLayout(new FillLayout(SWT.HORIZONTAL));
		
		//LEFT PANEL//////////////////////////////////////////////////////////
		Composite leftPanel = toolkit.createComposite(editorForm.getBody(), SWT.NONE);
		leftPanel.setLayout(new GridLayout(1, false));
		toolkit.paintBordersFor(leftPanel);
		
		//Set template
		templateSection = toolkit.createSection(leftPanel, Section.TWISTIE | Section.TITLE_BAR);
		templateSection.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		toolkit.paintBordersFor(templateSection);
		templateSection.setText("Template");
		templateSection.setExpanded(true);
		
		Composite templateSectionPanel = toolkit.createComposite(templateSection, SWT.NONE);
		toolkit.paintBordersFor(templateSectionPanel);
		templateSection.setClient(templateSectionPanel);
		templateSectionPanel.setLayout(new GridLayout(2, false));
		
		comboViewer = new ComboViewer(templateSectionPanel, SWT.READ_ONLY);
		comboViewer.setContentProvider(new ArrayContentProvider());
		comboViewer.setLabelProvider(new LabelProvider(){
			public String getText(Object element) {
				if (element instanceof Template) {
					return ((Template) element).getName();
			    }
			    return super.getText(element);
			}
		});
		comboViewer.setInput(Model.getModel().getTemplates());
		Combo combo = comboViewer.getCombo();
		combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		toolkit.paintBordersFor(combo);
		
		Button setTemplateButton = toolkit.createButton(templateSectionPanel, "Set", SWT.NONE);
		setTemplateButton.addSelectionListener(new SelectionAdapter() {
	    	public void widgetSelected(SelectionEvent e) {
	    		boolean result = MessageDialog.openConfirm(getShell(), "Set template", "If you set a new template, actual constraint will be replaced!");
	    		if(result){
	    			ISelection selection = comboViewer.getSelection();
	    			if (selection != null && selection instanceof IStructuredSelection) {
	    				Object obj = ((IStructuredSelection) selection).getFirstElement();
	    				if (obj instanceof Template) {
	    					ConstraintEditorView.this.controller.setTemplate(((Template)obj).getId());
	    					templateSection.setExpanded(false);
	    				}
	    			}
	    			
	    		}
	    	}
		});
		
		Composite composite = new Composite(templateSectionPanel, SWT.NONE);
		composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 2, 1));
		toolkit.adapt(composite);
		toolkit.paintBordersFor(composite);
		composite.setLayout(new GridLayout(2, false));
		
		ImageHyperlink createTemplateLink = toolkit.createImageHyperlink(composite, SWT.NONE);
		toolkit.paintBordersFor(createTemplateLink);
		createTemplateLink.setText("Create new template");
		createTemplateLink.setImage(MyImages.NEW_FILE);
		createTemplateLink.addMouseListener(new MouseAdapter() {
			public void mouseDown(MouseEvent e) {
				ConstraintEditorView.this.controller.callTemplateEditor(CallEditor.NEW_TEMPLATE);
			}
		});
		
		ImageHyperlink createTemplateFromConstraintLink = toolkit.createImageHyperlink(composite, SWT.NONE);
		toolkit.paintBordersFor(createTemplateFromConstraintLink);
		createTemplateFromConstraintLink.setText("Create template from this constraint");
		createTemplateFromConstraintLink.setImage(MyImages.NEW_FILE);
		createTemplateFromConstraintLink.addMouseListener(new MouseAdapter() {
			public void mouseDown(MouseEvent e) {
				ConstraintEditorView.this.controller.createNewTemplateFromConstraint();
			}
		});
		
		ToolBar toolbar = new ToolBar(templateSection, SWT.NONE);
		templateSection.setTextClient(toolbar);
		ToolItem refreshItem = new ToolItem(toolbar, SWT.NONE);
		refreshItem.setImage(MyImages.REFRESH);
		refreshItem.setToolTipText("Refresh template list");
		refreshItem.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				comboViewer.refresh();
			}
		});
		
		

		//Constraint (name, context, severity)
		Section constraintSection = toolkit.createSection(leftPanel, Section.TWISTIE | Section.TITLE_BAR);
		constraintSection.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		toolkit.paintBordersFor(constraintSection);
		constraintSection.setText("Constraint");
		constraintSection.setExpanded(true);
		
		Composite constraintSectionPanel = toolkit.createComposite(constraintSection, SWT.NONE);
		toolkit.paintBordersFor(constraintSectionPanel);
		constraintSection.setClient(constraintSectionPanel);
		constraintSectionPanel.setLayout(new GridLayout(3, false));
		
		Label annotationLabel = toolkit.createLabel(constraintSectionPanel, "Annotation", SWT.NONE);
		
		Label annotationInfoLabel = new Label(constraintSectionPanel, SWT.NONE);
		annotationInfoLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		annotationInfoLabel.setImage(MyImages.INFO);
		annotationInfoLabel.setToolTipText("Info...");
		
		annotationTextfield = new Text(constraintSectionPanel, SWT.BORDER);
		annotationTextfield.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		toolkit.adapt(annotationTextfield, true, true);
		DropTarget target = new DropTarget(annotationTextfield, DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT);
		target.setTransfer(new Transfer[] {TextTransfer.getInstance()});
		target.addDropListener(new ConstraintEditorDropAdapter() {
			@Override
			public void drop(DropTargetEvent event) {
				if (TextTransfer.getInstance().isSupportedType(event.currentDataType)) {
			        DropTarget target = (DropTarget) event.widget;
		        	if(target.getControl() instanceof Text){
		        		((Text) target.getControl()).setText((String) event.data);	
		        	}
				}
			}
		});
		
		Label contextLabel = toolkit.createLabel(constraintSectionPanel, "Context", SWT.NONE);
		
		Label contextInfoLabel = new Label(constraintSectionPanel, SWT.NONE);
		contextInfoLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		contextInfoLabel.setImage(MyImages.INFO);
		contextInfoLabel.setToolTipText("Info...");
		
		contextCombo = new Combo(constraintSectionPanel, SWT.READ_ONLY);
		contextCombo.setItems(new String[] {"METHOD", "FIELD", "PARAMETER", "TYPE", " "});
		contextCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		toolkit.adapt(contextCombo);
		toolkit.paintBordersFor(contextCombo);
		contextCombo.select(4);
		
		Label severityLabel = toolkit.createLabel(constraintSectionPanel, "Severity", SWT.NONE);
		
		Label severityInfoLabel = new Label(constraintSectionPanel, SWT.NONE);
		severityInfoLabel.setImage(MyImages.INFO);
		severityInfoLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		severityInfoLabel.setToolTipText("Info...");
		
		severityCombo = new Combo(constraintSectionPanel, SWT.READ_ONLY);
		severityCombo.setItems(new String[] {"ERROR", "WARNING"});
		severityCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		toolkit.adapt(severityCombo);
		toolkit.paintBordersFor(severityCombo);
		severityCombo.select(0);
		
		//RULES SECTION
		DropTargetAdapter rulePanelDropListener = new ConstraintEditorDropAdapter() {
			@Override
			public void drop(DropTargetEvent event) {
				if (TextTransfer.getInstance().isSupportedType(event.currentDataType)) {
			        DropTarget target = (DropTarget) event.widget;
			        String data = (String) event.data;
			        StringTokenizer st = new StringTokenizer(data, ":");
			        String rule = st.nextToken();
			        String ruleType = st.nextToken();
			        if(target.getControl() instanceof Composite){
			        	String panelName = (String) target.getControl().getData("name");
			        	if(panelName!=null){
			        		if (panelName.equals("rulesSectionPanel")) {
			        			controller.addRuleElementToRules(ruleType, rule);
							}
			        		else if (panelName.equals("conditionSectionPanel")) {
			        			controller.addRuleElementToConditions(ruleType, rule);
							}
			        	}
			        }
			    }
			}
		};
		
		rulesSection = toolkit.createSection(leftPanel, Section.TWISTIE | Section.TITLE_BAR);
		GridData gd_rulesSection = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
		gd_rulesSection.heightHint = 57;
		rulesSection.setLayoutData(gd_rulesSection);
		toolkit.paintBordersFor(rulesSection);
		rulesSection.setText("Rules");
		rulesSection.setExpanded(true);
		
		rulesSectionPanel = toolkit.createComposite(rulesSection, SWT.NONE);
		toolkit.paintBordersFor(rulesSectionPanel);
		rulesSection.setClient(rulesSectionPanel);
		rulesSectionPanel.setLayout(new GridLayout(1, false));
		rulesSectionPanel.setData("name", "rulesSectionPanel");
		target = new DropTarget(rulesSectionPanel, DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT);
		target.setTransfer(new Transfer[] {TextTransfer.getInstance()});
		target.addDropListener(rulePanelDropListener);
		
		emptyRulePanelLabel = new Label(rulesSectionPanel, SWT.NONE);
		toolkit.adapt(emptyRulePanelLabel, true, true);
		emptyRulePanelLabel.setText("[Drag here some rules]");
		
		//CONDITON SECTION
		conditionSection = toolkit.createSection(leftPanel, Section.TWISTIE | Section.TITLE_BAR);
		conditionSection.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		toolkit.paintBordersFor(conditionSection);
		conditionSection.setText("Condition");
		conditionSection.setExpanded(true);
				
		conditionSectionPanel = toolkit.createComposite(conditionSection, SWT.NONE);
		toolkit.paintBordersFor(conditionSectionPanel);
		conditionSection.setClient(conditionSectionPanel);
		conditionSectionPanel.setLayout(new GridLayout(1, false));
		conditionSectionPanel.setData("name", "conditionSectionPanel");
		target = new DropTarget(conditionSectionPanel, DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT);
		target.setTransfer(new Transfer[] {TextTransfer.getInstance()});
		target.addDropListener(rulePanelDropListener);
		
		emptyCondPanelLabel = new Label(conditionSectionPanel, SWT.NONE);
		toolkit.adapt(emptyCondPanelLabel, true, true);
		emptyCondPanelLabel.setText("[Drag here some rules]");
		
		//Save constraint
		Section saveSection = toolkit.createSection(leftPanel, Section.TWISTIE | Section.TITLE_BAR);
		saveSection.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		toolkit.paintBordersFor(saveSection);
		saveSection.setText("Save Constraint");
		saveSection.setExpanded(true);
		
		Composite saveSectionPanel = toolkit.createComposite(saveSection, SWT.NONE);
		toolkit.paintBordersFor(saveSectionPanel);
		saveSection.setClient(saveSectionPanel);
		saveSectionPanel.setLayout(new GridLayout(3, false));
		
		Label descriptionLabel = new Label(saveSectionPanel, SWT.NONE);
		toolkit.adapt(descriptionLabel, true, true);
		descriptionLabel.setText("Description: ");
		
		descriptionText = new Text(saveSectionPanel, SWT.BORDER);
		descriptionText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
		toolkit.adapt(descriptionText, true, true);
		
		Label nameLabel = new Label(saveSectionPanel, SWT.NONE);
		nameLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		toolkit.adapt(nameLabel, true, true);
		nameLabel.setText("Name: ");
		
		nameTextfield = new Text(saveSectionPanel, SWT.BORDER);
		nameTextfield.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		toolkit.adapt(nameTextfield, true, true);
		
		Button saveButton = new Button(saveSectionPanel, SWT.NONE);
		saveButton.setToolTipText("Save Changes");
		toolkit.adapt(saveButton, true, true);
		saveButton.setText("Save");
		saveButton.addSelectionListener(new SelectionAdapter() {
	    	public void widgetSelected(SelectionEvent e) {
	    		doSave();
	    	}
		});
		
		//RIGHT PANEL//////////////////////////////////////////////////////////
		Composite rightPanel = toolkit.createComposite(editorForm.getBody(), SWT.NONE);
		toolkit.paintBordersFor(rightPanel);
		rightPanel.setLayout(new GridLayout(1, false));
		
		//Rules section
		ruleChooserSection = toolkit.createSection(rightPanel, Section.TWISTIE | Section.TITLE_BAR);
		toolkit.paintBordersFor(ruleChooserSection);
		ruleChooserSection.setText("Available Rules");
		ruleChooserSection.setExpanded(true);
		Composite ruleChooserComposite = new RuleChooserPanel(ruleChooserSection, SWT.NONE);
		ruleChooserSection.setClient(ruleChooserComposite);	
				
		//Types section
		typeChooserSection = toolkit.createSection(rightPanel, Section.TWISTIE | Section.TITLE_BAR);
		toolkit.paintBordersFor(typeChooserSection);
		typeChooserSection.setText("Available Types");
		typeChooserSection.setExpanded(true);
		Composite typeChooserPanel = new TypeChooserPanel(typeChooserSection, SWT.NONE);
		typeChooserSection.setClient(typeChooserPanel);
				
		//Annotations section
		annotationsListSection = toolkit.createSection(rightPanel, Section.TWISTIE | Section.TITLE_BAR);
		annotationsListSection.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		toolkit.paintBordersFor(annotationsListSection);
		annotationsListSection.setText("Available Annotations");
		annotationsListSection.setExpanded(true);
		final Composite annotationChooserPanel = new AnnotationChooserPanel(annotationsListSection, CEController);
		annotationsListSection.setClient(annotationChooserPanel);
		
		toolbar = new ToolBar(annotationsListSection, SWT.NONE);
		annotationsListSection.setTextClient(toolbar);
		ToolItem addAnnotationsItem = new ToolItem(toolbar, SWT.NONE);
		addAnnotationsItem.setImage(MyImages.ADD_ANN);
		addAnnotationsItem.setToolTipText("Add annotations from project..");
		addAnnotationsItem.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				final ListSelectionDialog dlg = new ListSelectionDialog(getShell(), ResourcesPlugin.getWorkspace().getRoot(), new BaseWorkbenchContentProvider(), new WorkbenchLabelProvider(), "Select the Project:");
	    		dlg.setTitle("Project Selection");
	    		dlg.open();
	    		for (Object project : dlg.getResult()) {
					if(project instanceof IProject){
						((AnnotationChooserPanel) annotationChooserPanel).addProject((IProject) project);
					}
				}
	    		((AnnotationChooserPanel) annotationChooserPanel).createTree();
			}
		});
		ToolItem addJarsItem = new ToolItem(toolbar, SWT.NONE);
		addJarsItem.setImage(MyImages.ADD_LIB);
		addJarsItem.setToolTipText("Add annotations from jar..");
		addJarsItem.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				IPath[] paths = BuildPathDialogAccess.chooseJAREntries(getShell(), null, new IPath[0]);
	    		for (IPath path : paths) {
	    			((AnnotationChooserPanel) annotationChooserPanel).addJar(path);
				}
	    		((AnnotationChooserPanel) annotationChooserPanel).createTree();
			}
		});
//		ToolItem addExternalJarsItem = new ToolItem(toolbar, SWT.NONE);
//		addExternalJarsItem.setImage(MyImages.ADD);
//		addExternalJarsItem.setToolTipText("Add annotations from external jar..");
//		addExternalJarsItem.addSelectionListener(new SelectionAdapter() {
//			public void widgetSelected(SelectionEvent e) {
//				IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
//				IPath[] paths = BuildPathDialogAccess.chooseExternalJAREntries(getShell());
//	    		for (IPath path : paths) {
//	    			IFile file = workspaceRoot.getFile(path);
//	    			System.out.println(path.toString());
//	    			System.out.println(file.getName());
//	    			IProject project = file.getProject();
//	    			System.out.println(project.getName());
//				}
//	    		((AnnotationChooserPanel) annotationChooserPanel).createTree();
//			}
//		});
		ToolItem removeAnnotationsItem = new ToolItem(toolbar, SWT.NONE);
		removeAnnotationsItem.setImage(MyImages.REMOVE);
		removeAnnotationsItem.setToolTipText("Remove project from list");
		removeAnnotationsItem.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				((AnnotationChooserPanel) annotationChooserPanel).removeSelected();
			}
		});
	}
	
	/**
	 * Show constraint specified as parameter in GUI
	 * @param constraint to show
	 */
	public void showConstraint(Constraint constraint){
		editorForm.setText("Constraint: "+constraint.getName());
		nameTextfield.setText(constraint.getName());
		if(constraint.getAnnotationName()!=null){
			annotationTextfield.setText(constraint.getAnnotationName());
		}
		if(constraint.getDescription()!=null){
			descriptionText.setText(constraint.getDescription());
		}
		Context context = constraint.getContext();
		Severity severity = constraint.getSeverity();
		if(context==null)contextCombo.select(6);
		else contextCombo.select(contextCombo.indexOf(constraint.getContext().name()));
		if(severity==null)severityCombo.select(0);
		else severityCombo.select(severityCombo.indexOf(constraint.getSeverity().name()));
		//Remove old rulepanels if exists
		if(!rulePanels.isEmpty()){
			for (IRulePanel rulePanel : rulePanels) {
				rulePanel.dispose();
			}
		}
		//Show rule's rulepanels in rulesSection
		java.util.List<RuleElement> ruleElements = constraint.getRules().getElements();
		for (RuleElement element : ruleElements) {
			addRulePanel(element);
		}
		//If conditions exists, show its rulepanels in conditionSection 
		try{
			java.util.List<RuleElement> condElements = constraint.getConditions().getElements();
			for (RuleElement element : condElements) {
				addCondPanel(element);
			}
		}catch (NullPointerException e) {
			// Condition not exists - we can ignore it
		}
	}
	
	/**
	 * Add new rulepanel for specified element(rule) to ruleSection 
	 * @param element (from model) to show
	 */
	public void addRulePanel(RuleElement element){
		templateSection.setExpanded(false);
		if(!emptyRulePanelLabel.isDisposed())emptyRulePanelLabel.dispose();
		if(element instanceof SimpleRuleElement) rulePanels.add(new SimpleElementRulePanel(rulesSectionPanel, (SimpleRuleElement) element, controller, false));
		else if(element instanceof StructuredRuleElement) rulePanels.add(new StructuredElementRulePanel(rulesSectionPanel, (StructuredRuleElement) element, controller, false));
	}
	
	/**
	 * Add new rulepanel for specified element(condition) to conditionSection
	 * @param element (from model) to show
	 */
	public void addCondPanel(RuleElement element){
		templateSection.setExpanded(false);
		if(!emptyCondPanelLabel.isDisposed())emptyCondPanelLabel.dispose();
		if(element instanceof SimpleRuleElement) rulePanels.add(new SimpleElementRulePanel(conditionSectionPanel, (SimpleRuleElement) element, controller, false));
		else if(element instanceof StructuredRuleElement) rulePanels.add(new StructuredElementRulePanel(conditionSectionPanel, (StructuredRuleElement) element, controller, false));
	}
	
	/**
	 * Save created or edited constraint
	 */
	public void doSave(){
		for (IRulePanel panel : rulePanels) {
			panel.doSave();
		}
		controller.saveConstraint(nameTextfield.getText(), annotationTextfield.getText(), contextCombo.getText(), severityCombo.getText(), descriptionText.getText());
	}
}
